﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Shapes;

namespace UBCon.Navigation
{

    internal class DeferredDragAdorner : Adorner
    {
        #region Constructors

        /// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="adornedElement"></param>
        internal DeferredDragAdorner(UIElement adornedElement)
            : base(adornedElement)
        {
            Content = BuildContent();

            Content.RenderTransform = translate;

            //Content.IsHitTestVisible = false;
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets visual representation of adorner.
        /// </summary>
        private Rectangle Content
        {
            get
            {
                return _content;
            }
            set
            {
                _content = value;
            }
        }

        /// <summary>
        /// Gets horizontal distance that the mouse has moved.
        /// </summary>
        internal double HorizontalChange 
        {
            get 
            {
                return translate.X;
            }
        }
        #endregion

        #region Depenency Property Changed Callbacks
        #endregion

        #region Overrides

        protected override int VisualChildrenCount
        {
            get
            {
                return 1;
            }
        }

        protected override Visual GetVisualChild(int index)
        {
            return Content;
        }

        /// <summary>
        /// Invalidates the measurement state (layout) for the element. (Inherited from UIElement.)
        /// </summary>
        /// <param name="availableSize">The available size that this element can give to child elements. 
        /// Infinity can be specified as a value to indicate that the element will size to whatever content is available.</param>
        /// <returns>The size that this element determines it needs during layout, based on its calculations of child element sizes.</returns>
        protected override Size MeasureOverride(Size constraint)
        {
            measureSize.Width = 4.0D;
            measureSize.Height = constraint.Height;
            return measureSize;
        }

        /// <summary>
        /// Invalidates the arrange state (layout) for the element. 
        /// After the invalidation, the element will have its layout updated, which will occur 
        /// asynchronously unless subsequently forced by UpdateLayout. (Inherited from UIElement.)
        /// </summary>
        /// <param name="finalSize">The finalSize size that this element can give to child elements. 
        /// Infinity can be specified as a value to indicate that the element will size to whatever content is available.</param>
        /// <returns>The size that this element determines it needs during layout, based on its calculations of child element sizes.</returns>
        protected override Size ArrangeOverride(Size finalSize)
        {
            OutlookBar element = AdornedElement as OutlookBar;
            if (element != null)
            {
                arrangeRect.X = element.PaneWidth - 10;
                arrangeRect.Y = 0;
                arrangeRect.Width = 4.0D;
                arrangeRect.Height = finalSize.Height;

                Content.Arrange(arrangeRect);
            }
            return finalSize;
        }
        #endregion

        #region public Methods
        #endregion

        #region Internal Methods

        /// <summary>
        /// Updates adorner's position with specified point.
        /// </summary>
        /// <param name="point"></param>
        internal void UpdatePosition(double hChange)
        {
            translate.X = hChange + 2;
            InvalidateMeasure();
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Builds visual representation of adorner.
        /// </summary>
        /// <returns>Type: System.Windows.Shapes.Rectangle</returns>
        private Rectangle BuildContent() 
        {
            Rectangle rect = new Rectangle()
            {
                Width=4.0,
                Cursor=System.Windows.Input.Cursors.ScrollWE
            };

            ComponentResourceKey key = new ComponentResourceKey(typeof(SkinManagers.SkinManager), "GrayBrush");

            SolidColorBrush brush = NavigationHelper.GetSkinResourceByKey<SolidColorBrush>(key);

            rect.Fill = brush != null ? brush : Brushes.Gray;

            return rect;
        }
        #endregion

        #region Event Handlers
        #endregion

        #region Fields

        private TranslateTransform translate = new TranslateTransform();

        private Rectangle _content;

        private Rect arrangeRect = new Rect();

        private Size measureSize = new Size();
        
        #endregion

    }
}
